#include <stdio.h>
#include <unistd.h>
#include <error.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <signal.h>
#include <libgen.h>

#define CMD_SIZE 200
// 孤儿进程
int main(int argc, char *argv[])
{
    printf("Parent PID: %d\n", getpid());
    
    pid_t id = fork();
    if(id == -1)
    {
        perror("fork failed");
        return 1;
    }
    else if(id == 0)
    {
        int count = 5;
        while(1)
        {
            printf("I am a child process, PID:%d, PPID:%d\n", getpid(), getppid());
            if(getppid() == 1)
            {
                count--;
                if(count == 0)
                    exit(EXIT_SUCCESS);
            }
            sleep(1);
        }
    }
    else 
    {
        sleep(3);
        printf("\nparent process is about to exit, PID:%d\n\n", getpid());
        exit(EXIT_SUCCESS);
    }
}


// 僵尸进程
// int main(int argc, char *argv[])
// {
//     printf("Parent PID: %d\n", getpid());
//     
//     pid_t id = fork();
//     if(id == -1)
//     {
//         perror("fork failed");
//         return 1;
//     }
//     else if(id == 0)
//     {
//         printf("Child exiting, PID = %d\n", getpid());
//         _exit(EXIT_SUCCESS);
//     }
//     else 
//     {
//         sleep(3);
//         char cmd[CMD_SIZE];
//         snprintf(cmd, CMD_SIZE, "ps ajx | head -1 && ps ajx | grep %s | grep -v grep", basename(argv[0]));
//         cmd[CMD_SIZE] = '\0';
//         system(cmd);
// 
//         if(kill(id, SIGKILL) == -1)
//             perror("kill");
//         sleep(3);
//         printf("After spending SIGKILL to zombie(PID:%d)\n", id);
//         system(cmd);
//         exit(EXIT_SUCCESS);
//     }
//     return 0;
// }







// fork初始
// int main()
// {
//     pid_t id = fork();
// 
//     // fork之后，代码共享
//     printf("I am %s process, PID: %d\n", (id > 0) ? "parent": "child", getpid());
// 
//     return 0;
// }


// int main()
// {
//     pid_t id = fork();
//     if(id == -1)
//     {
//         perror("fork");
//         exit(EXIT_FAILURE);
//     }
//     else if(id == 0)
//     {
//         // child process
//         char *argv[] = { "ls", "-l", "-a", NULL };
//         execvp(argv[0], argv);
// 
//         // 如果函数返回了，子进程就会执行到这里，输出错误信息
//         perror("execvp failed");
//     }
//     else 
//     {
//         // parent process
//         int status;
//         if(waitpid(id, &status, 0) == -1)
//             perror("waitpid failed");
// 
//         if(WIFEXITED(status))
//             printf("child exited with status %d\n", WEXITSTATUS(status));
//     }
//     return 0;
// }


// int main()
// {
//     int a = 0;
//     a++;
//     execl("/usr/bin/pwd", "pwd", (char*)NULL);
//     printf("%d\n", a++);
//     return 0;
// }





// int main()
// {
//     pid_t pid = fork();
// 
//     if(pid < 0)
//     {
//         fprintf(stderr, "Fork failed\n");
//         return 1;
//     }
//     else if(pid == 0)
//     {
//         // child process
//         printf("I am child process\n");
//         sleep(5);
//         exit(0); // child exits with status code 0
//     }
//     else 
//     {
//         // parent process
//         int status;
//         waitpid(pid, &status, WNOHANG);
//         if(WIFEXITED(status))
//         {
//             printf("Child exited with status %d\n", WEXITSTATUS(status));
//         }
//         else if(WIFSIGNALED(status))
//         {
//             printf("Child was terminated by signal %d\n", WTERMSIG(status));
//             // if(WCOREDUMP(status))
//             // {
//             //     printf("Child produced a cor dump.\n");
//             // }
//         }
//         else if(WIFSTOPPED(status))
//         {
//             printf("Child was stopped by signal %d", WSTOPSIG(status));
//         }
//         exit(0); // Exit the parent process 
//     }
//     return 0;
// }












// int main()
// {
//     fork();
//     fork() && fork() || fork();
//     fork();
//     printf("I am a process, PID: %d\n", getpid());
//     return 0;
// }






// int main()
// {
//     for(int i = 0; i < 256; i++)
//     {
//         printf("%d:%s\n", i, strerror(i));
//     }
//     return 0;
// }








// int main(int argc, char *argv[])
// {
//     printf("Hello world\n");
//     write(STDOUT_FILENO, "Ciao\n", 5);
//     
//     if(fork() == -1)
//     {
//         perror("fork");
//     }
// 
//     /* Both child and parent continue execution here*/
//     return 0;
// }



// 
// int main(int argc, char *argv[])
// {
//     int istack = 222; /* stack segment*/
//     pid_t childPid;
// 
//     switch(childPid = fork())
//     {
//         case -1:
//             perror("fork()");
//         case 0:
//             idata *= 3;
//             istack *= 3;
//             break;
//         default:
//             sleep(3);
//             break;
//     }
//     /* Both parent and child come here */
//     printf("PID=%ld %s idata=%d istack=%d\n", (long)getpid(), (childPid == 0) ? "(child) " : "(parent)", idata, istack);
//     return 0;
// }
